package dk.iha;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager.OnActivityResultListener;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.content.DialogInterface;

public class SensorLoggerActivity extends Activity {

	Button startBtn;
	Button stopBtn;
	Button stopActivity;
	Button startRecording;
	Button SelectBTBTN;
	TextView btDevice = null;
	EditText emailAddress = null;
	EditText uniqueId = null;
	IntentFilter mIntentFilter = null;
	ListView listView = null;
	ArrayAdapter<String> debugDataAdapter = null;



	/**
	 * Updates the logStrings structure and returns true if structure has
	 * changed
	 * 
	 * @return
	 */
	void updateLogStrings() {
		List<String> logStrings = new ArrayList<String>( SharedData.getInstance().getDebugData() );
		if (logStrings.size() == 0)
			debugDataAdapter.add("No debug data yet!");

		debugDataAdapter.clear();
		for (String a : logStrings) {
			debugDataAdapter.add(a);
		}

		// update adapter
		debugDataAdapter.notifyDataSetChanged();
		listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
		// listView.setStackFromBottom(true);
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// Log.w("LIFETIME", "SensorLoggerActivity.onCreate");
		super.onCreate(savedInstanceState);

		// Initialise logging interface
		ConfigureLog4J.configure();

		// setup a handler for unhandled exceptions and log these to sdcard and logcat
		Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler());

		// initialize SharedData
		SharedData.getInstance().setContext(this);
		// Log.w("USER", "MainActivity.onCreate");
		setContentView(R.layout.main);
		/* UI components */
		startBtn = (Button) findViewById(R.id.startBTN);
		stopBtn = (Button) findViewById(R.id.stopBTN);
		uniqueId = (EditText) findViewById(R.id.uniqueID);
		stopActivity = (Button) findViewById(R.id.stopActivityBTN);
		startRecording = (Button) findViewById(R.id.startRecordingBTN);
		emailAddress = (EditText) findViewById(R.id.email_address);
		listView = (ListView) findViewById(R.id.listViewStatus);
		SelectBTBTN =  (Button) findViewById(R.id.SelectBTBTN);
		btDevice =  (TextView) findViewById(R.id.btdevice);

		int visibility = SharedPreferences.DEBUG ? View.VISIBLE	: View.INVISIBLE;
		stopActivity.setVisibility(visibility);
		startRecording.setVisibility(visibility);
		listView.setVisibility(visibility);
		// listView.setBackgroundColor(Color.RED);
		debugDataAdapter = new ArrayAdapter<String>(this, R.layout.mylist, new ArrayList<String>());
		listView.setAdapter(debugDataAdapter);

		UpdateUI();


		/* Listeners */
		// Start clicked
		startBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				//Check if mail address seems OK
				if (!emailAddress.getText().toString().matches("[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+") || 
						emailAddress.getText().toString().length() == 0) {
					showToastWithMessage("Email address is invalid. Please enter a valid email address.");
					return;
				}

				//Check if the Unique ID is ok
				if (uniqueId.getText().toString().equals("")) {
					showToastWithMessage("You must enter a unique ID, before starting");
					return;
				}

				
				//Check if GPS is enabled if not then guide the user to the GPS security activity
				if(SharedPreferences.ENABLE_GPS){
					if(!SharedData.isGPSEnabled(SensorLoggerActivity.this)){
						//show dialog "do you wish to enable gps?"
						AlertDialog alertDialog = new AlertDialog.Builder(SensorLoggerActivity.this).create(); 
						alertDialog.setTitle("Enable GPS");
						alertDialog.setMessage( getString(R.string.app_name) + " requires GPS to operate.\r\nDo you wish to enable the GPS now?");
						alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int which) {
								//OK clicked, start GPS security activity
								Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS );
								startActivity(myIntent);
							}});
						alertDialog.setButton2("Cancel", new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int which) {
								//Cancel clicked, back to UI => do nonthing
							}});
						alertDialog.setIcon(R.drawable.healthlogger_icon);
						alertDialog.show();
						return;
					}
				}

				//Check if Bluetooth device is selected, if not; bring up a dialog
				if(device == null){
					//show dialog "do you wish to enable gps?"
					AlertDialog alertDialog = new AlertDialog.Builder(SensorLoggerActivity.this).create(); 
					alertDialog.setTitle("Select Bluetooth device");
					alertDialog.setMessage( getString(R.string.app_name) + " requires a selected Bluetooth device to log temperature data. If a device is not selected no temperature measurements will be performed.\r\nDo you wish to continue without a device?");
					alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							//OK clicked
							startAfterChecks();
						}});
					alertDialog.setButton2("Cancel", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							//Cancel clicked, back to UI => do nonthing
						}});
					alertDialog.setIcon(R.drawable.healthlogger_icon);
					alertDialog.show();
					return;
				}

				startAfterChecks();
			}
		});


		// stopBtn clicked
		stopBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (!serviceRef.isNetworkAvailable()) {
					showToastWithMessage("Network is not available!! Pls your check your WIFI/3G connection");
				}
				serviceRef.stopDataCollection();
				UpdateUI();
				// Service is stopped by it self when it is done processing...
			}
		});

		// StopActivity clicked
		stopActivity.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// Log.w("USER", "Stop activity clicked");
				// closes Activity (UI)
				finish();
			}
		});
		// StartRecording clicked
		startRecording.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				soundSensor = new SoundSensor(null);
				soundSensor.startRecording();
				//SharedData.getInstance().addDebugDataLog_t("Start recording mic sound");
				recordTimer = new Timer();
				recordTimer.schedule(new TimerTask() {

					@Override
					public void run() {
						soundSensor.stopRecording();
						//SharedData.getInstance().addDebugDataLog_t("Stop recording mic sound");
					}}, 10000); //record for 10 secs
			}
		});
		
		
		SelectBTBTN.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
				//start the BT device select activity
				SelectBTDevice();
			}
		});
		
		// Create IntentFilter
		// This filter enables us to catch the broadcastmessages defined
		mIntentFilter = new IntentFilter();
		mIntentFilter.addAction(SharedPreferences.BROADCAST_MESSAGE_SERVICE_STATE_CHANGED);
		mIntentFilter.addAction(SharedPreferences.BROADCAST_MESSAGE_SERVICE_DEBUG_STATE_CHANGED);
	}




	private void startAfterChecks(){
		// Start datacollection service in response to user input
		Intent intent = new Intent(SensorLoggerActivity.this, SensorLoggerService.class);
		//explicit start of service 
		// Service will kill itself explicitly on end datacollection
		startService(intent);
		StartDateCollection();
	}



	String btDeviceAddress = null;
	final int requestCodeLcl = 1;
	/**
	 * Starts a new activity and  let the user select BT device
	 */
	private void SelectBTDevice(){
		Intent intent = new Intent(this, SelectBTDeviceActivity.class);
		startActivityForResult(intent, requestCodeLcl);

	}
	BluetoothDevice device=null;
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.w("vv", "onActivityResult:"+requestCode);
		if (requestCodeLcl == requestCode) {
			if(resultCode == RESULT_OK){

				device = (BluetoothDevice) data.getParcelableExtra("BTDevice");
				if(device != null){
					//we have successfully received our device address
					Log.w("fdfd", "device : "+device.getName());
					btDevice.setText(device.getName());
				}
			}

			if (resultCode == RESULT_CANCELED) {

				//Write your code on no result return 

			}
		}
	}













	SoundSensor soundSensor;
	Timer recordTimer;

	// listen for broadcasts from the Service
	private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// Called when state changes in the service
			UpdateUI();
		}
	};

	/**
	 * Interrogates the service and updates the UI accordingly  
	 */
	private void UpdateUI() {
		boolean running = false;
		// Log.w("LIFETIME", "UpdateUI - serviceRef is:" +
		updateLogStrings();

		if (null != serviceRef) {
			running = serviceRef.isDataCollectionRunning(); 
			// Log.w("LIFETIME", "Unique id: "+serviceRef.getUniqueId());
			if(running)
				uniqueId.setText(serviceRef.getUniqueId());
			emailAddress.setText(serviceRef.getEmailAddress());
			startBtn.setEnabled(!running && serviceRef.canStartDatacollection());
			SelectBTBTN.setEnabled(!running);

		} else {
			startBtn.setEnabled(true);
		}

		if (running) {
			// disabled
			emailAddress.setFocusable(false);
			emailAddress.setEnabled(false);
			uniqueId.setFocusable(false);
			uniqueId.setEnabled(false);
		} else {
			// enabled
			emailAddress.setFocusableInTouchMode(true);
			emailAddress.setEnabled(true);
			uniqueId.setFocusableInTouchMode(true);
			uniqueId.setEnabled(true);
		}
		stopBtn.setEnabled(running);
	}

	protected void onDestroy() {
		Log.w("LIFETIME", "SensorLoggerActivity.onDestroy");
		super.onDestroy();
	}

	private void bindService() {
		// Bind the service to the activity (BIND_AUTO_CREATE)
		Intent intent = new Intent(this, SensorLoggerService.class);
		bindService(intent, mConnection, BIND_AUTO_CREATE | BIND_DEBUG_UNBIND);
	}

	private void unbindService() {
		if (serviceRef != null) {
			unbindService(mConnection);
			serviceRef = null;
		}
	}

	@Override
	protected void onStart() {
		// Bind the service to the activity (BIND_AUTO_CREATE) 
		bindService();
		super.onStart();
	}

	@Override
	protected void onStop() {
		// Log.w("LIFETIME", "SensorLoggerActivity.onStop");
		// unbind the activity from the service
		unbindService();
		super.onStop();
	}

	@Override
	protected void onPause() {
		// Log.w("LIFETIME", "SensorLoggerActivity.onPause");
		unregisterReceiver(mIntentReceiver);
		super.onPause();
	}

	@Override
	protected void onResume() {
		// Log.w("LIFETIME", "SensorLoggerActivity.onResume");
		// register listener for broadcast message
		registerReceiver(mIntentReceiver, mIntentFilter);
		UpdateUI();
		super.onResume();
	}

	private void showToastWithMessage(String message) {
		Context context = getApplicationContext();
		CharSequence text = message;
		int duration = Toast.LENGTH_SHORT;
		Toast toast = Toast.makeText(context, text, duration);
		toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
		toast.show();
	}

	private void StartDateCollection() {
		String uniqueIdtxt = SensorLoggerActivity.this.uniqueId.getText().toString();
		String emailAddress = SensorLoggerActivity.this.emailAddress.getText().toString();
		serviceRef.setUniqueId(uniqueIdtxt);
		serviceRef.setBluetoothDevice(device);
		serviceRef.setEmailAddress(emailAddress);
		serviceRef.startDataCollection();
	}

	// Reference to the service STARTS
	private SensorLoggerService serviceRef = null;
	// Handles the connection between the service and activity
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			// Called when the connection is made.
			serviceRef = ((SensorLoggerService.MyBinder) service).getService();
			UpdateUI();
		}

		public void onServiceDisconnected(ComponentName className) {
			// Received when the service disconnects.
			serviceRef = null;
		}
	};
	// Reference to the service STOPS

}